package com.linrui.car.service.impl;

import com.linrui.basic.config.MyResultMapper;
import com.linrui.basic.utils.PageList;
import com.linrui.car.es.doc.CarDoc;
import com.linrui.car.es.repository.CarDocRepository;
import com.linrui.car.query.CarSearchQuery;
import com.linrui.car.service.ICarSearchService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
public class CarSearchServiceImpl implements ICarSearchService {

    @Autowired
    private CarDocRepository carDocRepository;

    @Autowired
    private MyResultMapper myResultMapper;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @Override
    public PageList<CarDoc> search(CarSearchQuery query) {

        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();

        BoolQueryBuilder booleanQuery = QueryBuilders.boolQuery();
        if (StringUtils.isNoneBlank(query.getKeyword())){
            booleanQuery.must(QueryBuilders.multiMatchQuery(query.getKeyword(), "title","shopName","typeName","carInfo"));
        }

        Long typeId = query.getTypeId();
        Integer costeffective = query.getCosteffective();
        Integer rushsale = query.getRushsale();
        Integer quasinewcar = query.getQuasinewcar();
        Integer transitivecountry = query.getTransitivecountry();
        if (typeId != null){
            booleanQuery.filter(QueryBuilders.termQuery("typeId", typeId));
        }else if (costeffective != null){
            booleanQuery.filter(QueryBuilders.termQuery("costeffective", costeffective));
        }else
        if (rushsale != null){
            booleanQuery.filter(QueryBuilders.termQuery("rushsale", rushsale));
        }else
        if (quasinewcar != null){
            booleanQuery.filter(QueryBuilders.termQuery("quasinewcar", quasinewcar));
        }else
        if (transitivecountry != null){
            booleanQuery.filter(QueryBuilders.termQuery("transitivecountry", transitivecountry));
        }

        //价格
        BigDecimal minPrice = query.getMinPrice();
        BigDecimal maxPrice = query.getMaxPrice();
        if(minPrice != null){
            booleanQuery.filter(QueryBuilders.rangeQuery("costprice").gte(minPrice));
        }
        if(maxPrice != null){
            booleanQuery.filter(QueryBuilders.rangeQuery("costprice").lte(maxPrice));
        }

        // 车龄
        Integer carAge = query.getCarAge();
        Integer carAgeType = query.getCarAgeType();

        if(carAge != null && carAgeType != null){
            carAge = 0 - carAge;
            Date date = DateUtils.addYears(new Date(), carAge);
            if(carAgeType == 0){
                booleanQuery.filter(QueryBuilders.rangeQuery("reigstertime").gte(date));
            }else if (carAgeType == 1){
                booleanQuery.filter(QueryBuilders.rangeQuery("reigstertime").lte(date));
            }
        }

        builder.withQuery(booleanQuery);

        //排序查询
        String sortField = query.getSortField();
        String sortType = query.getSortType();
        SortOrder sortOrder = SortOrder.DESC;

        if ("asc".equals(sortType)){
            sortOrder = SortOrder.ASC;
        }
        if("jg".equals(sortField)){
            builder.withSort(SortBuilders.fieldSort("costprice").order(sortOrder));
        }else if("cl".equals(sortField)){
            builder.withSort(SortBuilders.fieldSort("reigstertime").order(sortOrder));
        }else if("lc".equals(sortField)){
            builder.withSort(SortBuilders.fieldSort("mileage").order(sortOrder));
        }else if("zxfb".equals(sortField)){
            builder.withSort(SortBuilders.fieldSort("onsaletime").order(sortOrder));
        }
        //分页
        builder.withPageable(PageRequest.of((query.getCurrentPage()-1), query.getPageSize()));

        //高亮查询
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title");
        highlightBuilder.preTags("<span style=\"color:red;\">");
        highlightBuilder.postTags("</span>");
        builder.withHighlightBuilder(highlightBuilder);

        //调search到es中查询
        AggregatedPage<CarDoc> carDocs = elasticsearchTemplate.queryForPage(builder.build(), CarDoc.class, myResultMapper);

        List<CarDoc> content = carDocs.getContent();
        for (CarDoc doc : content) {
            String shopAddress = doc.getShopAddress();
            if(StringUtils.isNotBlank(shopAddress)){
                doc.setShopAddress(shopAddress.split("市")[0]);
            }
        }
        long total = carDocs.getTotalElements();
        return new PageList(total, content);
    }
}
